#include "dht11.h"

//DHT11数字温湿度传感器驱动代码	 
 
//要实现两个延时函数、4个io操作函数
void DHT11_delay_ms(u16 n)
{
	delay_us(n * 1000);
}
void DHT11_delay_us(u16 n)
{
	delay_us(n);
}
void DHT11_IO_IN()  
{
	HAL_GPIO_SetInOut(GPIOD, GPIO_PIN_6, ENABLE, DISABLE);
}
void DHT11_IO_OUT() 
{
	HAL_GPIO_SetInOut(GPIOD, GPIO_PIN_6, ENABLE, ENABLE);
}										   
void DHT11_DQ_OUT(u8 n)
{
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, !!n);
}
u8 DHT11_DQ_IN(void)
{
	return HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_6);
}

//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在    	 
u8 DHT11_init(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	GPIO_Initure.Pin = GPIO_PIN_6;
	GPIO_Initure.OutputEn = ENABLE;
	GPIO_Initure.InputEn = DISABLE;
	GPIO_Initure.PullupEn = DISABLE;
	HAL_GPIO_Init(GPIOD, &GPIO_Initure);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_SET);

	DHT11_rst();
	return DHT11_check();
}

//复位DHT11
void DHT11_rst(void)	   
{
	DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_DQ_OUT(0); 	//拉低DQ
    DHT11_delay_ms(20);    	//拉低至少18ms
    DHT11_DQ_OUT(1); 	//DQ=1 
	DHT11_delay_us(30);     	//主机拉高20~40us
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_check(void) 	   
{   
	u8 retry=0;
	DHT11_IO_IN();//SET INPUT	 
    while (DHT11_DQ_IN()&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		DHT11_delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!DHT11_DQ_IN()&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		DHT11_delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}
//从DHT11读取一个位
//返回值：1/0
u8 DHT11_read_bit(void) 			 
{
 	u8 retry=0;
	while(DHT11_DQ_IN() &&retry<100)//等待变为低电平
	{
		retry++;
		DHT11_delay_us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN() &&retry<100)//等待变高电平
	{
		retry++;
		DHT11_delay_us(1);
	}
	DHT11_delay_us(40);//等待40us
	if(DHT11_DQ_IN())return 1;
	else return 0;		   
}
//从DHT11读取一个字节
//返回值：读到的数据
u8 DHT11_read_byte(void)    
{        
    u8 i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_read_bit();
    }						    
    return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值：0,正常;1,读取失败
u8 DHT11_read_data(u8 *temp,u8 *humi)    
{        
 	u8 buf[5];
	u8 i;
	DHT11_rst();
	if(DHT11_check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_read_byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}

























